package com.icesoft.base.manager.controller.security.monitor;

import com.icesoft.core.common.helper.Resp;
import com.icesoft.core.common.log.LogFilter;
import com.icesoft.core.web.helper.RequestHold;
import com.icesoft.core.web.helper.ResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.boot.system.ApplicationPid;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 日志文件接口
 * */
@Slf4j
@RestController
@RequestMapping("security/log/")
public class LogFileController {

    /**
     * 查询日志文件列表
     * */
    @GetMapping("logFiles")
    public Resp<List<String>> logFiles(@RequestParam String logLevel) {
        try (Stream<Path> stream = Files.list(Paths.get(LogFilter.getLogFilePath() + "/" + logLevel))) {
            List<String> logs = stream.map(Path::getFileName).map(String::valueOf).filter(p -> p.endsWith(".zip"))
                    .sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            logs.add(0, logLevel + ".log");
            return Resp.success(logs);
        } catch (IOException e) {
            log.error("查找日志级别文件出现错误：" + logLevel, e);
            return Resp.error("查找出现错误");
        }
    }

    enum LogLevel {
        trace, debug, info, warn, error
    }
    /**
     * 下载日志文件接口
     * */
    @GetMapping("downloadLogFile")
    public Resp<Void> downloadLogFile(@RequestParam LogLevel logLevel, @RequestParam String fileName,
                                      HttpServletResponse response, HttpServletRequest request) {
        String logPath = LogFilter.getLogFilePath() + "/" + logLevel;
        Path path = null;
        try {
            path = Paths.get(logPath);
        } catch (InvalidPathException e) {
            log.error("路径错误", e);
            return Resp.error("路径错误：" + logPath);
        }

        try (Stream<Path> stream = Files.list(path);
             FileInputStream fis = new FileInputStream(stream.filter(p -> p.endsWith(fileName)).findFirst()
                     .orElseThrow(() -> new IOException("找不到文件：" + fileName)).toFile())) {
            log.info("ip:{}，下载日志文件：{}", RequestHold.getRemoteIP(request), fileName);
            ResponseUtils.writeToFileStream(response, fileName, fis);
            return null;
        } catch (IOException e) {
            log.error("downloadLogFile exception", e);
            return Resp.error("下载出现错误");
        }

    }
    /**
     * jstack下载接口
     * */
    @GetMapping("jstackFile")
    public Resp<Void> jstackFile(HttpServletResponse response) {
        Process process = null;
        try {
            String cmd = getJstackCommond();
            log.debug("jstack cmd：{}", cmd);
            process = Runtime.getRuntime().exec(cmd);
            String fileName = "jstack.txt";
            log.info("下载jstack数据，命令：{}", cmd);
            ResponseUtils.writeToFileStream(response, fileName, process.getInputStream());
        } catch (IOException e) {
            return Resp.error("执行异常：" + e.getMessage());
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
        return null;
    }

    private static String getJstackCommond() {
        String cmd = "jstack -l " + new ApplicationPid().toString();
        File javaHome = new File(SystemUtils.JAVA_HOME + "/../bin/");
        if (!javaHome.exists()) {
            return cmd;
        }
        return javaHome.toURI().getPath() + cmd;
    }
}
